home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmiSoft / Disk / moni / FileX-src.lha / FileX-src / filexarexx.c < prev    next >
C/C++ Source or Header  |  1994-05-16  |  24KB  |  1,301 lines

  1. /*
  2.  * Source generated with ARexxBox 1.11 (May  5 1993)
  3.  * which is Copyright (c) 1992,1993 Michael Balzer
  4.  *
  5.  * and heavily modified by Klaas Hermanns
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <dos/dos.h>
  11. #include <rexx/storage.h>
  12. #include <rexx/rxslib.h>
  13.  
  14. #include <clib/alib_protos.h>
  15. #include <clib/exec_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/rexxsyslib_protos.h>
  18.  
  19. #include <pragmas/exec_pragmas.h>
  20. #include <pragmas/dos_pragmas.h>
  21. #include <pragmas/rexxsyslib_pragmas.h>
  22.  
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27. #include <dos/rdargs.h>
  28.  
  29. #include "filexARexx.h"
  30.  
  31. #include "FileXStructs.h"
  32. #include "allprotos.h"
  33.  
  34. struct rxs_stemnode
  35. {
  36.     struct rxs_stemnode *succ;
  37.     char *name;
  38.     char *value;
  39. };
  40.  
  41.  
  42. void (*ARexxResultHook)( struct RexxHost *, struct RexxMsg * ) = NULL;
  43.  
  44.  
  45.  
  46. void ReplyRexxCommand(
  47.     struct RexxMsg    *rexxmessage,
  48.     long            primary,
  49.     long            secondary,
  50.     char            *result )
  51. {
  52.     if( rexxmessage->rm_Action & RXFF_RESULT )
  53.     {
  54.         if( primary == 0 )
  55.         {
  56.             secondary = result
  57.                 ? (long) CreateArgstring( result, strlen(result) )
  58.                 : (long) NULL;
  59.         }
  60.         else
  61.         {
  62.             char buf[16];
  63.             
  64.             if( primary > 0 )
  65.             {
  66.                 sprintf( buf, "%ld", secondary );
  67.                 result = buf;
  68.             }
  69.             else
  70.             {
  71.                 primary = -primary;
  72.                 result = (char *) secondary;
  73.             }
  74.             
  75.             SetRexxVar( (struct Message *) rexxmessage,
  76.                 "RC2", result, strlen(result) );
  77.             
  78.             secondary = 0;
  79.         }
  80.     }
  81.     else if( primary < 0 )
  82.         primary = -primary;
  83.     
  84.     rexxmessage->rm_Result1 = primary;
  85.     rexxmessage->rm_Result2 = secondary;
  86.     ReplyMsg( (struct Message *) rexxmessage );
  87. }
  88.  
  89.  
  90. void FreeRexxCommand( struct RexxMsg *rexxmessage )
  91. {
  92.     if( !rexxmessage->rm_Result1 && rexxmessage->rm_Result2 )
  93.         DeleteArgstring( (char *) rexxmessage->rm_Result2 );
  94.  
  95.     if( rexxmessage->rm_Stdin &&
  96.         rexxmessage->rm_Stdin != Input() )
  97.         Close( rexxmessage->rm_Stdin );
  98.  
  99.     if( rexxmessage->rm_Stdout &&
  100.         rexxmessage->rm_Stdout != rexxmessage->rm_Stdin &&
  101.         rexxmessage->rm_Stdout != Output() )
  102.         Close( rexxmessage->rm_Stdout );
  103.  
  104.     DeleteArgstring( (char *) ARG0(rexxmessage) );
  105.     DeleteRexxMsg( rexxmessage );
  106. }
  107.  
  108.  
  109. struct RexxMsg *CreateRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  110. {
  111.     struct RexxMsg *rexx_command_message;
  112.  
  113.     if( (rexx_command_message = CreateRexxMsg( host->port,
  114.         rexx_extension, host->port->mp_Node.ln_Name)) == NULL )
  115.     {
  116.         return( NULL );
  117.     }
  118.  
  119.     if( (rexx_command_message->rm_Args[0] =
  120.         CreateArgstring(buff,strlen(buff))) == NULL )
  121.     {
  122.         DeleteRexxMsg(rexx_command_message);
  123.         return( NULL );
  124.     }
  125.  
  126.     rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  127.     rexx_command_message->rm_Stdin  = fh;
  128.     rexx_command_message->rm_Stdout = fh;
  129.     
  130.     return( rexx_command_message );
  131. }
  132.  
  133.  
  134. struct RexxMsg *CommandToRexx( struct RexxHost *host, struct RexxMsg *rexx_command_message )
  135. {
  136.     struct MsgPort *rexxport;
  137.     
  138.     Forbid();
  139.  
  140.     if( (rexxport = FindPort(RXSDIR)) == NULL )
  141.     {
  142.         Permit();
  143.         return( NULL );
  144.     }
  145.  
  146.     PutMsg( rexxport, &rexx_command_message->rm_Node );
  147.     
  148.     Permit();
  149.     
  150.     ++host->replies;
  151.     return( rexx_command_message );
  152. }
  153.  
  154.  
  155. struct RexxMsg *SendRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  156. {
  157.     struct RexxMsg *rcm;
  158.     
  159.     if( rcm = CreateRexxCommand(host, buff, fh) )
  160.         return CommandToRexx( host, rcm );
  161.     else
  162.         return NULL;
  163. }
  164.  
  165.  
  166. void CloseDownARexxHost( struct RexxHost *host )
  167. {
  168.     struct RexxMsg *rexxmsg;
  169.     
  170.     if( host->port )
  171.     {
  172.         /* Port abmelden */
  173.         RemPort( host->port );
  174.         
  175.         /* Auf noch ausstehende Replies warten */
  176.         while( host->replies > 0 )
  177.         {
  178.             WaitPort( host->port );
  179.             
  180.             while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  181.             {
  182.                 if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  183.                 {
  184.                     if( !rexxmsg->rm_Args[15] )
  185.                     {
  186.                         /* Reply zu einem SendRexxCommand()-Call */
  187.                         if( ARexxResultHook )
  188.                             ARexxResultHook( host, rexxmsg );
  189.                     }
  190.                     
  191.                     FreeRexxCommand( rexxmsg );
  192.                     --host->replies;
  193.                 }
  194.                 else
  195.                     ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  196.             }
  197.         }
  198.         
  199.         /* MsgPort leeren */
  200.         while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  201.             ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  202.         
  203.         if( !(host->flags & ARB_HF_USRMSGPORT) )
  204.             DeleteMsgPort( host->port );
  205.     }
  206.     
  207.     if( host->rdargs ) FreeDosObject( DOS_RDARGS, host->rdargs );
  208.     FreeVec( host );
  209. }
  210.  
  211.  
  212. struct RexxHost *SetupARexxHost( char *basename, struct MsgPort *usrport )
  213. {
  214.     struct RexxHost *host;
  215.     int ext = 1;
  216.     
  217.     if( !basename )
  218.         basename = RexxPortBaseName;
  219.     else if( !*basename )
  220.         basename = RexxPortBaseName;
  221.     
  222.     if( !(host = AllocVec(sizeof *host, MEMF_CLEAR)) )
  223.         return NULL;
  224.     
  225.     strcpy( host->portname, basename );
  226.     
  227.     if( usrport )
  228.     {
  229.         host->port   = usrport;
  230.         host->flags |= ARB_HF_USRMSGPORT;
  231.     }
  232.     else if( !(host->port = CreateMsgPort()))
  233.     {
  234.         FreeVec( host );
  235.         return NULL;
  236.     }
  237.     else
  238.     {
  239.         host->port->mp_Node.ln_Pri = 0;
  240.     }
  241.     
  242.     Forbid();
  243.     
  244.     while( FindPort(host->portname) )
  245.         sprintf( host->portname, "%s.%ld", basename, ext++ );
  246.     
  247.     host->port->mp_Node.ln_Name = host->portname;
  248.     AddPort( host->port );
  249.     
  250.     Permit();
  251.     
  252.     if( !(host->rdargs = AllocDosObject(DOS_RDARGS, NULL)) )
  253.     {
  254.         RemPort( host->port );
  255.         if( !usrport ) DeleteMsgPort( host->port );
  256.         FreeVec( host );
  257.         return NULL;
  258.     }
  259.     
  260.     host->rdargs->RDA_Flags = RDAF_NOPROMPT;
  261.     
  262.     return( host );
  263. }
  264.  
  265.  
  266. struct rxs_command *FindRXCommand( char *com )
  267. {
  268.     struct rxs_command *rxc;
  269.     int n = strlen( com ), ug = 0, og = command_cnt - 1, pos, cmp;
  270.     
  271.     if( n == 0 )
  272.         return NULL;
  273.     
  274.     /* Init */
  275.     
  276.     pos = (og + ug) / 2;
  277.     rxc = rxs_commandlist + pos;
  278.     
  279.     /* Suchen */
  280.     
  281.     while((og>=ug) && (cmp = strnicmp(com, rxc->command,n)))
  282.     {
  283.         if(cmp < 0)
  284.             og = pos - 1;
  285.         else
  286.             ug = pos + 1;
  287.         
  288.         pos = (og + ug) / 2;
  289.         rxc = rxs_commandlist + pos;
  290.     }
  291.     
  292.     if(cmp)
  293.         return( NULL );
  294.     else
  295.     {
  296.         while((rxc!=rxs_commandlist) &&
  297.                 (cmp = strnicmp(com, (rxc-1)->command,n)==0))
  298.             rxc--;
  299.         
  300.         return(rxc);
  301.     }
  302. }
  303.  
  304.  
  305. static struct rxs_command *ParseRXCommand( char **arg )
  306. {
  307.     char com[256], *s, *t;
  308.     
  309.     s = *arg;
  310.     t = com;
  311.     
  312.     while( *s && *s != ' ' && *s != '\n' )
  313.         *t++ = *s++;
  314.     
  315.     *t = '\0';
  316.     while( *s == ' ' ) ++s;
  317.     *arg = s;
  318.     
  319.     return( FindRXCommand( com ) );
  320. }
  321.  
  322.  
  323. static char *CreateVAR( struct rxs_stemnode *stem )
  324. {
  325.     char *var;
  326.     struct rxs_stemnode *s;
  327.     long size = 0;
  328.     
  329.     if( !stem || stem == (struct rxs_stemnode *) -1L )
  330.         return( (char *) stem );
  331.     
  332.     for( s = stem; s; s = s->succ )
  333.         size += strlen( s->value ) + 1;
  334.     
  335.     if( !(var = AllocVec( size + 1, MEMF_ANY )) )
  336.         return( (char *) -1 );
  337.     
  338.     *var = '\0';
  339.     
  340.     for( s = stem; s; s = s->succ )
  341.     {
  342.         strcat( var, s->value );
  343.         if( s->succ )
  344.             strcat( var, " " );
  345.     }
  346.     
  347.     return( var );
  348. }
  349.  
  350.  
  351. static struct rxs_stemnode *new_stemnode( struct rxs_stemnode **first, struct rxs_stemnode **old )
  352. {
  353.     struct rxs_stemnode *new;
  354.     
  355.     if( !(new = AllocVec(sizeof(struct rxs_stemnode), MEMF_CLEAR)) )
  356.     {
  357.         return( NULL );
  358.     }
  359.     else
  360.     {
  361.         if( *old )
  362.         {
  363.             (*old)->succ = new;
  364.             (*old) = new;
  365.         }
  366.         else
  367.         {
  368.             *first = *old = new;
  369.         }
  370.     }
  371.     
  372.     return( new );
  373. }
  374.  
  375.  
  376. static void free_stemlist( struct rxs_stemnode *first )
  377. {
  378.     struct rxs_stemnode *next;
  379.     
  380.     if( (long) first == -1 )
  381.         return;
  382.     
  383.     for( ; first; first = next )
  384.     {
  385.         next = first->succ;
  386.         if( first->name  ) FreeVec( first->name );
  387.         if( first->value ) FreeVec( first->value );
  388.         FreeVec( first );
  389.     }
  390. }
  391.  
  392.  
  393. char *StrDup( char *s )
  394. {
  395.     char *t = AllocVec( strlen(s)+1, MEMF_ANY );
  396.     if( t ) strcpy( t, s );
  397.     return t;
  398. }
  399.  
  400.  
  401. static struct rxs_stemnode *CreateSTEM( struct rxs_command *rxc, LONG *resarray, char *stembase )
  402. {
  403.     struct rxs_stemnode *first = NULL, *old = NULL, *new;
  404.     char resb[512], *rs, *rb;
  405.     char longbuff[16];
  406.     
  407.     rb = resb;
  408.     if( stembase )
  409.     {
  410.         while( *stembase )
  411.             *rb++ = ToUpper( *stembase++ );
  412.     }
  413.     *rb = '\0';
  414.     
  415.     rb = resb + strlen(resb);
  416.     rs = rxc->results;
  417.     
  418.     while( *rs )
  419.     {
  420.         char *t = rb;
  421.         BOOL optn = FALSE, optm = FALSE;
  422.         
  423.         while( *rs && *rs != ',' )
  424.         {
  425.             if( *rs == '/' )
  426.             {
  427.                 ++rs;
  428.                 if( *rs == 'N' ) optn = TRUE;
  429.                 else if( *rs == 'M' ) optm = TRUE;
  430.             }
  431.             else
  432.                 *t++ = *rs;
  433.             
  434.             ++rs;
  435.         }
  436.         
  437.         if( *rs == ',' ) ++rs;
  438.         *t = '\0';
  439.         
  440.         /*
  441.          * Resultat(e) erzeugen
  442.          */
  443.         
  444.         if( !*resarray )
  445.         {
  446.             ++resarray;
  447.             continue;
  448.         }
  449.         
  450.         if( optm )
  451.         {
  452.             long *r, index = 0;
  453.             LONG **subarray = (LONG **) *resarray++;
  454.             struct rxs_stemnode *countnd;
  455.             
  456.             /* Anzahl der Elemente */
  457.             
  458.             if( !(new = new_stemnode(&first, &old)) )
  459.             {
  460.                 free_stemlist( first );
  461.                 return( (struct rxs_stemnode *) -1L );
  462.             }
  463.             countnd = new;
  464.             
  465.             /* Die Elemente selbst */
  466.             
  467.             while( r = *subarray++ )
  468.             {
  469.                 if( !(new = new_stemnode(&first, &old)) )
  470.                 {
  471.                     free_stemlist( first );
  472.                     return( (struct rxs_stemnode *) -1L );
  473.                 }
  474.                 
  475.                 sprintf( t, ".%ld", index++ );
  476.                 new->name = StrDup( resb );
  477.                 
  478.                 if( optn )
  479.                 {
  480.                     sprintf( longbuff, "%ld", *r );
  481.                     new->value = StrDup( longbuff );
  482.                 }
  483.                 else
  484.                 {
  485.                     new->value = StrDup( (char *) r );
  486.                 }
  487.             }
  488.             
  489.             /* Die Count-Node */
  490.             
  491.             strcpy( t, ".COUNT" );
  492.             countnd->name = StrDup( resb );
  493.             
  494.             sprintf( longbuff, "%ld", index );
  495.             countnd->value = StrDup( longbuff );
  496.         }
  497.         else
  498.         {
  499.             /* Neue Node anlegen */
  500.             if( !(new = new_stemnode(&first, &old)) )
  501.             {
  502.                 free_stemlist( first );
  503.                 return( (struct rxs_stemnode *) -1L );
  504.             }
  505.             
  506.             new->name = StrDup( resb );
  507.             
  508.             if( optn )
  509.             {
  510.                 sprintf( longbuff, "%ld", *((long *) *resarray) );
  511.                 new->value = StrDup( longbuff );
  512.                 ++resarray;
  513.             }
  514.             else
  515.             {
  516.                 new->value = StrDup( (char *) (*resarray++) );
  517.             }
  518.         }
  519.     }
  520.     
  521.     return( first );
  522. }
  523.  
  524.  
  525. static void DoRXCommand( struct RexxHost *host, struct RexxMsg *rexxmsg )
  526. {
  527.     struct rxs_command *rxc;
  528.     char *argb, *arg;
  529.     
  530.     LONG *array = NULL;
  531.     LONG *argarray;
  532.     LONG *resarray;
  533.     
  534.     char *cargstr = NULL;
  535.     long rc=20, rc2=0;
  536.     char *result = NULL;
  537.     
  538.     if( !(argb = AllocVec(strlen((char *) ARG0(rexxmsg)) + 2, MEMF_ANY)) )
  539.     {
  540.         rc2 = ERROR_NO_FREE_STORE;
  541.         goto drc_cleanup;
  542.     }
  543.     
  544.     /* welches Kommando? */
  545.     
  546.     strcpy( argb, (char *) ARG0(rexxmsg) );
  547.     strcat( argb, "\n" );
  548.     arg = argb;
  549.  
  550.     if( !( rxc = ParseRXCommand( &arg ) ) )
  551.     {
  552.         if( arg = ExpandRXCommand( host, (char *) ARG0(rexxmsg) ) )
  553.         {
  554.             FreeVec( argb );
  555.             if( !(argb = AllocVec( strlen(arg) + 2, MEMF_ANY )) )
  556.             {
  557.                 rc2 = ERROR_NO_FREE_STORE;
  558.                 goto drc_cleanup;
  559.             }
  560.             
  561.             strcpy( argb, arg );
  562.             strcat( argb, "\n" );
  563.             FreeVec( arg );
  564.             arg = argb;
  565.             
  566.             rxc = ParseRXCommand( &arg );
  567.         }
  568.     }
  569.     
  570.     if( !rxc )
  571.     {
  572.         /* Msg an ARexx schicken, vielleicht existiert ein Skript */
  573.         struct RexxMsg *rm;
  574.         
  575.         if( rm = CreateRexxCommand(host, (char *) ARG0(rexxmsg), NULL) )
  576.         {
  577.             /* Original-Msg merken */
  578.             rm->rm_Args[15] = (STRPTR) rexxmsg;
  579.             
  580.             if( CommandToRexx(host, rm) )
  581.             {
  582.                 /* Reply wird später vom Dispatcher gemacht */
  583.                 if( argb ) FreeVec( argb );
  584.                 return;
  585.             }
  586.             else
  587.                 rc2 = ERROR_NOT_IMPLEMENTED;
  588.         }
  589.         else
  590.             rc2 = ERROR_NO_FREE_STORE;
  591.         
  592.         goto drc_cleanup;
  593.     }
  594.     
  595.     if( !(rxc->flags & ARB_CF_ENABLED) )
  596.     {
  597.         rc = -10;
  598.         rc2 = (long) "Command disabled";
  599.         goto drc_cleanup;
  600.     }
  601.     
  602.     /* Speicher für Argumente etc. holen */
  603.     
  604.     if(!(rxc->flags & ARB_CF_OWNALLOC))
  605.         array=AllocVec(rxc->structsize,MEMF_CLEAR);
  606.  
  607.     if(rxc->flags & ARB_CF_CALLINIT)
  608.         (rxc->function)( host, (void **) &array, RXIF_INIT );
  609.  
  610.     cargstr = AllocVec( rxc->args ? 15+strlen(rxc->args) : 15, MEMF_ANY );
  611.  
  612.     if( !array || !cargstr )
  613.     {
  614.         rc2 = ERROR_NO_FREE_STORE;
  615.         goto drc_cleanup;
  616.     }
  617.     
  618.     argarray = array + 2;
  619.     resarray = array + rxc->resindex;
  620.     
  621.     /* Argumente parsen */
  622.     
  623.     if( rxc->results )
  624.         strcpy( cargstr, "VAR/K,STEM/K" );
  625.     else
  626.         *cargstr = '\0';
  627.     
  628.     if( rxc->args )
  629.     {
  630.         if( *cargstr )
  631.             strcat( cargstr, "," );
  632.         strcat( cargstr, rxc->args );
  633.     }
  634.     
  635.     if( *cargstr )
  636.     {
  637.         host->rdargs->RDA_Source.CS_Buffer = arg;
  638.         host->rdargs->RDA_Source.CS_Length = strlen(arg);
  639.         host->rdargs->RDA_Source.CS_CurChr = 0;
  640.         host->rdargs->RDA_DAList = NULL;
  641.         host->rdargs->RDA_Buffer = NULL;
  642.         
  643.         if( !ReadArgs(cargstr, argarray, host->rdargs) )
  644.         {
  645.             rc = 10;
  646.             rc2 = IoErr();
  647.             goto drc_cleanup;
  648.         }
  649.     }
  650.     
  651.     /* Funktion aufrufen */
  652.  
  653.     host->akturexxmsg=rexxmsg;
  654.     host->userdata=0;
  655.  
  656.     (rxc->function)( host, (void **) &array, RXIF_ACTION );
  657.  
  658.     rc = array[0];
  659.     rc2 = array[1];
  660.  
  661.     /* Resultat(e) auswerten */
  662.  
  663.     if(host->userdata==0)
  664.     if( rxc->results && rc==0 &&
  665.         (rexxmsg->rm_Action & RXFF_RESULT) )
  666.     {
  667.         struct rxs_stemnode *stem, *s;
  668.         
  669.         stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  670.         result = CreateVAR( stem );
  671.         
  672.         if( result )
  673.         {
  674.             if( argarray[0] )
  675.             {
  676.                 /* VAR */
  677.                 if( (long) result == -1 )
  678.                 {
  679.                     rc = 20;
  680.                     rc2 = ERROR_NO_FREE_STORE;
  681.                 }
  682.                 else
  683.                 {
  684.                     char *rb;
  685.                     
  686.                     for( rb = (char *) argarray[0]; *rb; ++rb )
  687.                         *rb = ToUpper( *rb );
  688.  
  689.                     if( SetRexxVar( (struct Message *) rexxmsg, (char *)argarray[0], result, strlen(result) ) )
  690.                     {
  691.                         rc = -10;
  692.                         rc2 = (long) "Unable to set Rexx variable";
  693.                     }
  694.                     
  695.                     FreeVec( result );
  696.                 }
  697.                 
  698.                 result = NULL;
  699.             }
  700.             
  701.             if( !rc && argarray[1] )
  702.             {
  703.                 /* STEM */
  704.                 if( (long) stem == -1 )
  705.                 {
  706.                     rc = 20;
  707.                     rc2 = ERROR_NO_FREE_STORE;
  708.                 }
  709.                 else
  710.                 {
  711.                     for( s = stem; s; s = s->succ )
  712.                         rc |= SetRexxVar( (struct Message *) rexxmsg, s->name, s->value, strlen(s->value) );
  713.                     
  714.                     if( rc )
  715.                     {
  716.                         rc = -10;
  717.                         rc2 = (long) "Unable to set Rexx variable";
  718.                     }
  719.                     
  720.                     if( result && (long) result != -1 )
  721.                         FreeVec( result );
  722.                 }
  723.                 
  724.                 result = NULL;
  725.             }
  726.             
  727.             /* Normales Resultat: Möglich? */
  728.             
  729.             if( (long) result == -1 )
  730.             {
  731.                 /* Nein */
  732.                 rc = 20;
  733.                 rc2 = ERROR_NO_FREE_STORE;
  734.                 result = NULL;
  735.             }
  736.         }
  737.         
  738.         free_stemlist( stem );
  739.     }
  740.     
  741. drc_cleanup:
  742.  
  743.     /* Nur RESULT, wenn weder VAR noch STEM */
  744.     
  745.     if(0==host->userdata)ReplyRexxCommand( rexxmsg, rc, rc2, result );
  746.     
  747.     /* benutzten Speicher freigeben */
  748.     
  749.     if( result ) FreeVec( result );
  750.     FreeArgs( host->rdargs );
  751.     if( cargstr ) FreeVec( cargstr );
  752.     if( array )
  753.     {
  754.         if(rxc->flags & ARB_CF_CALLFREE)
  755.             (rxc->function)( host, (void **) &array, RXIF_FREE );
  756.  
  757.         if(!(rxc->flags & ARB_CF_OWNALLOC))
  758.             FreeVec(array);
  759.     }
  760.  
  761.     if( argb ) FreeVec( argb );
  762. }
  763.  
  764.  
  765. void ARexxDispatch( struct RexxHost *host )
  766. {
  767.     struct RexxMsg *rexxmsg;
  768.  
  769.     while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  770.     {
  771.         if( (rexxmsg->rm_Action & RXCODEMASK) != RXCOMM )
  772.         {
  773.             /* Keine Rexx-Message */
  774.             ReplyMsg( (struct Message *) rexxmsg );
  775.         }
  776.         else if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  777.         {
  778.             struct RexxMsg *org = (struct RexxMsg *) rexxmsg->rm_Args[15];
  779.             
  780.             if( org )
  781.             {
  782.                 /* Reply zu durchgereichter Msg */
  783.                 if( rexxmsg->rm_Result1 != 0 )
  784.                 {
  785.                     /* Befehl unbekannt */
  786.                     ReplyRexxCommand( org, 20, ERROR_NOT_IMPLEMENTED, NULL );
  787.                 }
  788.                 else
  789.                 {
  790.                     ReplyRexxCommand( org, 0, 0, (char *) rexxmsg->rm_Result2 );
  791.                 }
  792.             }
  793.             else
  794.             {
  795.                 /* Reply zu einem SendRexxCommand()-Call */
  796.                 if( ARexxResultHook )
  797.                     ARexxResultHook( host, rexxmsg );
  798.             }
  799.             
  800.             FreeRexxCommand( rexxmsg );
  801.             --host->replies;
  802.         }
  803.         else if( ARG0(rexxmsg) )
  804.         {
  805.             DoRXCommand( host, rexxmsg );
  806.         }
  807.         else
  808.         {
  809.             ReplyMsg( (struct Message *) rexxmsg );
  810.         }
  811.     }
  812. }
  813.  
  814.  
  815. void DoShellCommand( struct RexxHost *host, char *comline, BPTR fhout )
  816. {
  817.     struct rxs_command *rxc;
  818.     char *argb, *arg;
  819.     
  820.     LONG *array = NULL;
  821.     LONG *argarray;
  822.     LONG *resarray;
  823.     
  824.     char *cargstr = NULL;
  825.     long rc=10, rc2=0;
  826.     
  827.     if( !(argb = AllocVec( strlen(comline) + 2, MEMF_ANY )) )
  828.     {
  829.         rc2 = ERROR_NO_FREE_STORE;
  830.         goto dsc_cleanup;
  831.     }
  832.     
  833.     /* welches Kommando? */
  834.     
  835.     strcpy( argb, comline );
  836.     strcat( argb, "\n" );
  837.     arg = argb;
  838.     
  839.     if( !( rxc = ParseRXCommand( &arg ) ) )
  840.     {
  841.         if( arg = ExpandRXCommand( host, comline ) )
  842.         {
  843.             FreeVec( argb );
  844.             if( !(argb = AllocVec( strlen(arg) + 2, MEMF_ANY )) )
  845.             {
  846.                 rc2 = ERROR_NO_FREE_STORE;
  847.                 goto dsc_cleanup;
  848.             }
  849.             
  850.             strcpy( argb, arg );
  851.             strcat( argb, "\n" );
  852.             FreeVec( arg );
  853.             arg = argb;
  854.             
  855.             rxc = ParseRXCommand( &arg );
  856.         }
  857.     }
  858.     
  859.     if( !rxc )
  860.     {
  861.         /* Msg an ARexx schicken, vielleicht existiert ein Skript */
  862.         struct RexxMsg *sentrm, *rm;
  863.         
  864.         if( sentrm = SendRexxCommand(host, comline, NULL) )
  865.         {
  866.             /* auf den Reply warten */
  867.             BOOL waiting = TRUE;
  868.             
  869.             while( waiting )
  870.             {
  871.                 WaitPort( host->port );
  872.                 
  873.                 while( rm = (struct RexxMsg *) GetMsg(host->port) )
  874.                 {
  875.                     /* Reply? */
  876.                     if( rm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  877.                     {
  878.                         /* zu diesem Kommando? */
  879.                         if( rm == sentrm )
  880.                         {
  881.                             if( rm->rm_Result1 )
  882.                             {
  883.                                 rc  = 20;
  884.                                 rc2 = ERROR_NOT_IMPLEMENTED;
  885.                             }
  886.                             else
  887.                             {
  888.                                 rc = rc2 = 0;
  889.                                 if( rm->rm_Result2 )
  890.                                     FPrintf( fhout, "%s\n", rm->rm_Result2 );
  891.                             }
  892.                             
  893.                             waiting = FALSE;
  894.                         }
  895.                         
  896.                         FreeRexxCommand( rm );
  897.                         --host->replies;
  898.                     }
  899.                     
  900.                     /* sonst Kommando -> Fehler */
  901.                     else
  902.                     {
  903.                         ReplyRexxCommand( rm, -20, (long)
  904.                             "CommandShell Port", NULL );
  905.                     }
  906.                 }
  907.             } /* while waiting */
  908.         }
  909.         else
  910.             rc2 = ERROR_NO_FREE_STORE;
  911.         
  912.         goto dsc_cleanup;
  913.     }
  914.     
  915.     if( !(rxc->flags & ARB_CF_ENABLED) )
  916.     {
  917.         rc = -10;
  918.         rc2 = (long) "Command disabled";
  919.         goto dsc_cleanup;
  920.     }
  921.     
  922.     /* Speicher für Argumente etc. holen */
  923.     
  924.     if(!(rxc->flags & ARB_CF_OWNALLOC))
  925.         array=AllocVec(rxc->structsize,MEMF_CLEAR);
  926.  
  927.     if(rxc->flags & ARB_CF_CALLINIT)
  928.         (rxc->function)( host, (void **) &array, RXIF_INIT );
  929.  
  930.     cargstr = AllocVec( rxc->args ? 512+strlen(rxc->args) : 512, MEMF_ANY );
  931.     
  932.     if( !array || !cargstr )
  933.     {
  934.         rc2 = ERROR_NO_FREE_STORE;
  935.         goto dsc_cleanup;
  936.     }
  937.     
  938.     argarray = array + 2;
  939.     resarray = array + rxc->resindex;
  940.     
  941.     /* Argumente parsen */
  942.     
  943.     *cargstr = '\0';
  944.     
  945.     if( rxc->results )
  946.         strcpy( cargstr, "VAR/K,STEM/K" );
  947.     
  948.     if( rxc->args )
  949.     {
  950.         if( *cargstr )
  951.             strcat( cargstr, "," );
  952.         strcat( cargstr, rxc->args );
  953.     }
  954.     
  955.     if( *cargstr )
  956.     {
  957.         host->rdargs->RDA_Source.CS_Buffer = arg;
  958.         host->rdargs->RDA_Source.CS_Length = strlen(arg);
  959.         host->rdargs->RDA_Source.CS_CurChr = 0;
  960.         host->rdargs->RDA_DAList = NULL;
  961.         host->rdargs->RDA_Flags  = RDAF_NOPROMPT;
  962.         
  963.         if( !ReadArgs(cargstr, argarray, host->rdargs) )
  964.         {
  965.             rc = 10;
  966.             rc2 = IoErr();
  967.             goto dsc_cleanup;
  968.         }
  969.     }
  970.     
  971.     /* Funktion aufrufen */
  972.     
  973.     host->outfh=fhout;
  974.  
  975.     (rxc->function)( host, (void **) &array, RXIF_ACTION );
  976.     
  977.     /* Resultat(e) ausgeben */
  978.     
  979.     if( rxc->results && array[0]==0 && fhout )
  980.     {
  981.         struct rxs_stemnode *stem, *s;
  982.         char *result;
  983.         
  984.         stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  985.         result = CreateVAR( stem );
  986.         
  987.         if( result )
  988.         {
  989.             if( argarray[0] )
  990.             {
  991.                 /* VAR */
  992.                 char *rb;
  993.                 
  994.                 if( (long) result == -1 )
  995.                 {
  996.                     free_stemlist( stem );
  997.                     rc2 = ERROR_NO_FREE_STORE;
  998.                     goto dsc_cleanup;
  999.                 }
  1000.                 
  1001.                 for( rb = (char *) argarray[0]; *rb; ++rb )
  1002.                     *rb = ToUpper( *rb );
  1003.                 
  1004.                 FPrintf( fhout, "%s = %s\n", argarray[0], result );
  1005.                 FreeVec( result );
  1006.                 result = NULL;
  1007.             }
  1008.             
  1009.             if( argarray[1] )
  1010.             {
  1011.                 /* STEM */
  1012.                 if( (long) stem == -1 )
  1013.                 {
  1014.                     rc2 = ERROR_NO_FREE_STORE;
  1015.                     goto dsc_cleanup;
  1016.                 }
  1017.                 
  1018.                 for( s = stem; s; s = s->succ )
  1019.                     FPrintf( fhout, "%s = %s\n", s->name, s->value );
  1020.                 
  1021.                 if( result && (long) result != -1 )
  1022.                     FreeVec( result );
  1023.                 result = NULL;
  1024.             }
  1025.             
  1026.             free_stemlist( stem );
  1027.             
  1028.             /* Normales Resultat: Möglich? */
  1029.             
  1030.             if( result )
  1031.             {
  1032.                 if( (long) result != -1L )
  1033.                 {
  1034.                     /* Ja */
  1035.                     FPrintf( fhout, "%s\n", result );
  1036.                     FreeVec( result );
  1037.                 }
  1038.                 else
  1039.                 {
  1040.                     rc2 = ERROR_NO_FREE_STORE;
  1041.                     goto dsc_cleanup;
  1042.                 }
  1043.             }
  1044.         }
  1045.     }
  1046.  
  1047.     /* Rückgabewert */
  1048.  
  1049.     rc  = array[0];
  1050.     rc2 = array[1];
  1051.  
  1052. dsc_cleanup:
  1053.  
  1054.     arg = NULL;
  1055.     
  1056.     if( rc2 )
  1057.     {
  1058.         if( !cargstr ) cargstr = AllocVec( 512, MEMF_ANY );
  1059.         
  1060.         if( !cargstr )
  1061.         {
  1062.             arg = "ERROR: Absolutely out of memory";
  1063.         }
  1064.         else if( rc > 0 )
  1065.         {
  1066.             if( Fault( rc2, "ERROR", cargstr, 512 ) )
  1067.                 arg = cargstr;
  1068.             else
  1069.                 arg = "ERROR: Unknown Problem";
  1070.         }
  1071.         else if( rc < 0 )
  1072.         {
  1073.             strcpy( cargstr, "ERROR: " );
  1074.             strncat( cargstr, (char *) rc2, 500 );
  1075.             arg = cargstr;
  1076.         }
  1077.     }
  1078.     
  1079.     if( arg ) FPrintf( fhout, "%s\n", arg );
  1080.     
  1081.     /* benutzten Speicher freigeben */
  1082.     
  1083.     if( cargstr ) FreeVec( cargstr );
  1084.     if( array )
  1085.     {
  1086.         if(rxc->flags & ARB_CF_CALLFREE)
  1087.             (rxc->function)( host, (void **) &array, RXIF_FREE );
  1088.  
  1089.         if(!(rxc->flags & ARB_CF_OWNALLOC))
  1090.             FreeVec(array);
  1091.     }
  1092.     if( argb ) FreeVec( argb );
  1093.     FreeArgs( host->rdargs );
  1094. }
  1095.  
  1096.  
  1097. static struct StandardPacket *CreateStdPkt( void )
  1098. {
  1099.     struct StandardPacket *sp;
  1100.  
  1101.     if( sp = AllocMem( sizeof( struct StandardPacket ), MEMF_PUBLIC ))
  1102.     {
  1103.         if( sp->sp_Msg.mn_ReplyPort = CreatePort( NULL, 0 ))
  1104.         {
  1105.             sp->sp_Msg.mn_Node.ln_Name = ( char * )&sp->sp_Pkt;
  1106.             sp->sp_Pkt.dp_Link = &sp->sp_Msg;
  1107.             return( sp );
  1108.         }
  1109.         FreeMem( sp, sizeof( struct StandardPacket ));
  1110.     }
  1111. }
  1112.  
  1113. static void DeleteStdPkt( struct StandardPacket *sp )
  1114. {
  1115.     DeletePort( sp->sp_Msg.mn_ReplyPort );
  1116.     FreeMem( sp, sizeof( struct StandardPacket ));
  1117. }
  1118.  
  1119. static void SendStdPkt( struct StandardPacket *sp, struct MsgPort *mp )
  1120. {
  1121.     sp->sp_Pkt.dp_Port = sp->sp_Msg.mn_ReplyPort;
  1122.     
  1123.     PutMsg( mp, &sp->sp_Msg );
  1124. }
  1125.  
  1126. static BOOL PacketUnterwegs;
  1127. static BPTR CSfh;
  1128. static char *CSbuffer;
  1129. static struct StandardPacket *CSsp;
  1130.  
  1131. void CloseCommandShell( void )
  1132. {
  1133.     if( MyRexxHost->flags & ARB_HF_CMDSHELL )
  1134.     {
  1135.         MyRexxHost->flags &= ~ARB_HF_CMDSHELL;
  1136.         MyRemoveSignal(  1 << CSsp->sp_Msg.mn_ReplyPort->mp_SigBit );
  1137.  
  1138.         Close( CSfh );
  1139.         CSfh = NULL;
  1140.  
  1141.         if( PacketUnterwegs )
  1142.         {
  1143. /*            Wait(  1 << CSsp->sp_Msg.mn_ReplyPort->mp_SigBit );*/
  1144.             GetMsg( CSsp->sp_Msg.mn_ReplyPort );
  1145.             PacketUnterwegs = FALSE;
  1146.         }
  1147.     
  1148.         DeleteStdPkt( CSsp );
  1149.         CSsp = NULL;
  1150.     
  1151.         FreeMem( CSbuffer, 1024 );
  1152.         CSbuffer = NULL;
  1153.     }
  1154. }
  1155.  
  1156. void DoCommandShellMsg( void )
  1157. {
  1158.     LONG rc1/*, rc2*/;
  1159.  
  1160.     GetMsg( CSsp->sp_Msg.mn_ReplyPort );
  1161.  
  1162.     PacketUnterwegs = FALSE;
  1163.  
  1164. /*    rc2 = CSsp->sp_Pkt.dp_Res2;*/
  1165.     rc1 = CSsp->sp_Pkt.dp_Res1;
  1166.  
  1167.         /* EOF ? */
  1168.  
  1169.     if( rc1 == 0 )
  1170.     {
  1171.         CloseCommandShell();
  1172.     }
  1173.     else
  1174.     {
  1175.         struct FileHandle *FH;
  1176.         char *s = CSbuffer;
  1177.  
  1178.         while( *s==' ' || *s=='\t' ) s++;
  1179.             
  1180.         if( *s != '\n' )
  1181.             DoShellCommand( MyRexxHost, s, CSfh );
  1182.  
  1183. /*        CSbuffer[ rc1-1 ] = 0;*/
  1184.  
  1185.         Write( CSfh, "->", 2 );
  1186.         
  1187.         FH = BADDR( CSfh );
  1188.         
  1189.         CSsp->sp_Pkt.dp_Type = ACTION_READ;
  1190.         CSsp->sp_Pkt.dp_Arg1 = FH->fh_Arg1;
  1191.         CSsp->sp_Pkt.dp_Arg3 = 1024;    /* BUFFERSIZE */
  1192.                     
  1193.         CSsp->sp_Pkt.dp_Arg2 = (long)CSbuffer;    /* Datenzeiger */
  1194.                     
  1195.         SendStdPkt( CSsp, FH->fh_Type );
  1196.         PacketUnterwegs = TRUE;
  1197.     }
  1198. }
  1199.  
  1200. BOOL OpenCommandShell( void )
  1201. {
  1202.     struct FileHandle *FH;
  1203.  
  1204.     if( MyRexxHost->flags & ARB_HF_CMDSHELL )
  1205.         return( TRUE );
  1206.  
  1207.     if( CSfh = Open(arexxcommandshellwindow, MODE_NEWFILE ))
  1208.     {
  1209.         FH = BADDR( CSfh );
  1210.     
  1211.         if( FH->fh_Type )
  1212.         {
  1213.             if( CSbuffer = AllocMem( 1024, MEMF_ANY ))
  1214.             {
  1215.                 if( CSsp = CreateStdPkt() )
  1216.                 {
  1217.                     MyRexxHost->flags |= ARB_HF_CMDSHELL;
  1218.     
  1219.                     Write( CSfh, "->", 2 );
  1220.             
  1221.                     CSsp->sp_Pkt.dp_Type = ACTION_READ;
  1222.                     CSsp->sp_Pkt.dp_Arg1 = FH->fh_Arg1;
  1223.                     CSsp->sp_Pkt.dp_Arg3 = 1024;    /* BUFFERSIZE */
  1224.                         
  1225.                     CSsp->sp_Pkt.dp_Arg2 = (long)CSbuffer;    /* Datenzeiger */
  1226.                         
  1227.                     SendStdPkt( CSsp, FH->fh_Type );
  1228.                     PacketUnterwegs = TRUE;
  1229.             
  1230.                     MyAddSignal( 1 << CSsp->sp_Msg.mn_ReplyPort->mp_SigBit, &DoCommandShellMsg );
  1231.                     return( TRUE );
  1232.                 }
  1233.         
  1234.                 FreeVec( CSbuffer );
  1235.                 CSbuffer = NULL;
  1236.             }
  1237.         }
  1238.  
  1239.         Close( CSfh );
  1240.     }
  1241.  
  1242.     return( FALSE );
  1243.  
  1244. /*    char comline[512], *s;
  1245.     struct RexxMsg *rm;
  1246.  
  1247.     if( !fhin )
  1248.         return;
  1249.     
  1250.     host->flags |= ARB_HF_CMDSHELL;
  1251.     do
  1252.     {
  1253.         /* Prompt ausgeben */
  1254.         
  1255.         if( fhout && prompt )
  1256.             FPuts( fhout, prompt );
  1257.         
  1258.         /* Befehl einlesen und abarbeiten */
  1259.         
  1260.         if( s = FGets(fhin, comline, 512) )
  1261.         {
  1262.             while( *s==' ' || *s=='\t' ) s++;
  1263.             
  1264.             if( *s != '\n' )
  1265.                 DoShellCommand( host, s, fhout );
  1266.         }
  1267.         else
  1268.         {
  1269.             host->flags &= ~ARB_HF_CMDSHELL;
  1270.         }
  1271.         
  1272.         /* Port des Hosts leeren (asynchrone Replies) */
  1273.         
  1274.         while( rm = (struct RexxMsg *) GetMsg(host->port) )
  1275.         {
  1276.             /* Reply? */
  1277.             if( rm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  1278.             {
  1279.                 if( !rm->rm_Args[15] )
  1280.                 {
  1281.                     /* Reply zu einem SendRexxCommand()-Call */
  1282.                     if( ARexxResultHook )
  1283.                         ARexxResultHook( host, rm );
  1284.                 }
  1285.                 
  1286.                 FreeRexxCommand( rm );
  1287.                 --host->replies;
  1288.             }
  1289.             
  1290.             /* sonst Kommando -> Fehler */
  1291.             else
  1292.             {
  1293.                 ReplyRexxCommand( rm, -20, (long)
  1294.                     "CommandShell Port", NULL );
  1295.             }
  1296.         }
  1297.     }
  1298.     while( host->flags & ARB_HF_CMDSHELL );*/
  1299. }
  1300.  
  1301.